package com.jackstraw.jack_base.remote_command.controller;

import com.jackstraw.jack_base.remote_command.entity.Conn;
import com.jackstraw.jack_base.remote_command.entity.UploadVo;
import com.jackstraw.jack_base.remote_command.config.JschConfig;
import com.jackstraw.jack_base.remote_command.entity.ExecuteCmd;
import com.jackstraw.jack_base.remote_command.entity.JackSoftProperties;
import com.jackstraw.jack_base.remote_command.entity.ModelEnum;
import com.jackstraw.jack_base.remote_command.pool.entity.SessiontConnectionConfig;
import com.jackstraw.jack_base.remote_command.service.GroupControlService;
import com.jackstraw.jack_base.remote_command.service.JschService;
import com.jackstraw.jack_base.remote_command.service.impl.AbstractGroupControlServiceImpl;
import com.jackstraw.jack_base.util.SpringUtil;
import com.jackstraw.jack_base.util.exception.BadRequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/execute")
public class RemoteExecuteController {

    @Autowired
    private JschConfig jschConfig;

    @Autowired
    private JschService jschService;

    @Autowired
    private GroupControlService groupControlService;

    @GetMapping("/listProperties")
    public List<SessiontConnectionConfig> listProperties() {
        return new ArrayList<>(jschConfig.getSessiontConnectionConfigMap().values());
    }

    @PutMapping("/connEnable/{connName}")
    public void connEnable(@PathVariable(value = "connName") String connName) {
        SessiontConnectionConfig sessiontConnectionConfig = jschConfig.getSessiontConnectionConfigMap().get(connName);
        if (ObjectUtils.isNotEmpty(sessiontConnectionConfig)) {
            Boolean enable = sessiontConnectionConfig.getEnable();
            if (enable) {
                this.jschConfig.logout(connName);
                sessiontConnectionConfig.setEnable(!enable);
            }
            if (!enable) {
                sessiontConnectionConfig.setEnable(!enable);
                this.jschConfig.login(sessiontConnectionConfig);
            }
        }
    }

    @PostMapping("/newProperties")
    public void newProperties(@RequestBody SessiontConnectionConfig sessiontConnectionConfig) {
        if (!sessiontConnectionConfig.getEnable()) {
            sessiontConnectionConfig.setEnable(Boolean.TRUE);
        }
    }

    @PutMapping("/exec/{modelEnum}")
    public List<String> exec(@PathVariable(value = "modelEnum") ModelEnum modelEnum, @RequestBody ExecuteCmd executeCmd) throws Exception {
        if (ModelEnum.one.equals(modelEnum)) {
            return new ArrayList<>(
                    Collections.singleton(
                            jschService
                                    .execShell(Conn.buildExec(executeCmd.getConnName()), executeCmd.getCommand())));
        } else if (ModelEnum.more.equals(modelEnum)) {
            return jschService
                    .execShell(Conn.buildExec(executeCmd.getConnName()), executeCmd.getCommandList());
        }
        return null;
    }

    @PutMapping("/execGroupControl/{modelEnum}/{softName}/{systemName}")
    public List<String> execGroupControl(@PathVariable(value = "modelEnum") ModelEnum modelEnum, @PathVariable(value = "softName") String softName, @PathVariable(value = "systemName") String systemName) {
        softName = groupControlService.concatSoftName(softName, systemName);
        JackSoftProperties.SoftProperties softProperties = groupControlService.getJackSoftPropertiesMap().get(softName);
        if (ObjectUtils.isEmpty(softProperties)) {
            log.warn("查询状态----------配置错误，请检查----------softName：{}----------systemName：{}", softName, systemName);
            return null;
        }
        GroupControlService groupControlService = this.groupControlService;
        //判断是否是docker部署
        if (!softProperties.getDockerFlag()) {
            String beanName = softProperties.getSoftName().concat(AbstractGroupControlServiceImpl.GROUP_CONTROL_SERVICE_IMPL);
            groupControlService = SpringUtil.getBean(beanName, GroupControlService.class);
        }
        try {
            switch (modelEnum) {
                case jackstats:
                    return new ArrayList<>(Collections.singleton(groupControlService.jackStats(softName, systemName).toString()));
                case jackstart:
                    return groupControlService.jackStart(softName, systemName);
                case jackstop:
                    return groupControlService.jackStop(softName, systemName);
                case jackrestart:
                    return groupControlService.jackReStart(softName, systemName);
                case stats:
                    return new ArrayList<>(Collections.singleton(groupControlService.stats(softName, systemName).toString()));
                case start:
                    return groupControlService.start(softName, systemName);
                case stop:
                    return groupControlService.stop(softName, systemName);
                case restart:
                    return groupControlService.restart(softName, systemName);
                default:
                    return null;
            }
        } catch (Exception e) {
            log.error("安装软件{}失败，失败原因为：{}", softName, e);
            throw new BadRequestException("3400000001", "安装软件{}失败", softName);
        }
    }

    @PutMapping("/execGroupControl/{modelEnum}/{softName}")
    public List<String> execGroupControlByDefaultSystemName(@PathVariable(value = "modelEnum") ModelEnum modelEnum, @PathVariable(value = "softName") String softName) {
        return this.execGroupControl(modelEnum, softName, null);
    }


    @PutMapping("/upload")
    public Boolean upload(@RequestBody UploadVo uploadVo) {
        try {
            jschService.upload(Conn.buildSftp(uploadVo.getConnName()), uploadVo.getDirectory(), uploadVo.getUploadFile());
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error("上传文件失败，异常原因为:{}", e);
            throw new BadRequestException("3300000001", "上传文件失败");
        }
    }

}

